#include "opt_parser.h"

using std::vector;
using std::string;

OptParser::OptParser(int argc, char* argv[], char* pattern, bool exit_on_error):
options(vector<int>(128, -1)), argv_index(0), argc(argc), exit_on_error(exit_on_error) {
	for (int i = 0; i < argc; i++) {
		this->argv.push_back(argv[i]);
	}
	for (char *c = pattern; *c; c++) {
		if ('a' <= *c && *c <= 'z' || 'A' <= *c && *c <= 'Z' || *c == '?') {
		    options[*c] = 0;
            if (*(c + 1) == ':') {
                options[*c] = 1;
                if (*(c + 2) == ':') {
                    options[*c] = 2;
                    c++;
                }
                c++;
            }
		} else {
		    fprintf(stderr, "Wrong option pattern.\n");
		    exit(-1);
		}
	}
}

int OptParser::next_opt() {
    argv_index++;
    if (argv_index == argc) {
        return 0;
    }
    if (argv[argv_index][0] == '-') {
        char c = argv[argv_index][1];
        if ('?' == c || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
            if (options[c] == 0 && argv[argv_index][2] == 0) {
                param = "";
                return c;
            }
            if (options[c] == 1) {
                if (argv[argv_index][2] == 0) {
                    argv_index++;
                    if (argv_index == argc) {
                        fprintf(stderr, "Missing option for -%c.\n", c);
                        if (exit_on_error) {
                            exit(-1);
                        } else {
                            return -1;
                        }
                    }
                    param = string(argv[argv_index]);
                } else {
                    param = string(argv[argv_index] + 2);
                }
                return c;
            }
            if (options[c] == 2) {
                if (argv[argv_index][2] == 0) {
                    fprintf(stderr, "Missing option for -%c.\n", c);
                    if (exit_on_error) {
                        exit(-1);
                    } else {
                        return -1;
                    }
                }
                param = string(argv[argv_index] + 2);
                return c;
            }
        }
    }
    // param directly given
    param = string(argv[argv_index]);
    return 1;
}
